home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
101-125
/
118
/
empire
/
src
/
source.zoo
/
cmd_map.d
< prev
next >
Wrap
Text File
|
1987-12-02
|
11KB
|
487 lines
#include:util.g
#empire.g
#empfunc.g
/*
* near - return true if the addressed sector is near one owned by the given
* country.
*/
proc near(int r, c; uint user; *uint dir)bool:
Sector_t s;
uint dummy;
bool noDir;
if dir = nil then
noDir := true;
dir := &dummy;
else
noDir := false;
fi;
readSector(r, c + 1, s);
if s.s_owner = user and (noDir or s.s_quantity[it_military] ~= 0) then
dir* := 2;
true
else
readSector(r, c - 1, s);
if s.s_owner = user and (noDir or s.s_quantity[it_military] ~= 0) then
dir* := 6;
true
else
readSector(r + 1, c - 1, s);
if s.s_owner = user and
(noDir or s.s_quantity[it_military] ~= 0) then
dir* := 5;
true
else
readSector(r + 1, c, s);
if s.s_owner = user and
(noDir or s.s_quantity[it_military] ~= 0) then
dir* := 4;
true
else
readSector(r + 1, c + 1, s);
if s.s_owner = user and
(noDir or s.s_quantity[it_military] ~= 0) then
dir* := 3;
true
else
readSector(r - 1, c - 1, s);
if s.s_owner = user and
(noDir or s.s_quantity[it_military] ~= 0) then
dir* := 7;
true
else
readSector(r - 1, c, s);
if s.s_owner = user and
(noDir or
s.s_quantity[it_military] ~= 0) then
dir* := 0;
true
else
readSector(r - 1, c + 1, s);
if s.s_owner = user and
(noDir or
s.s_quantity[it_military] ~= 0) then
dir* := 1;
true
else
false
fi
fi
fi
fi
fi
fi
fi
fi
corp;
/*
* digit printing routines for mapping.
*/
proc digit1(int x)void:
write(Chout;
if x <= -10 then
-x / 10 + '0'
elif x < 0 then
'-'
else
x / 10 + '0'
fi
);
corp;
proc digit2(int x)void:
write(Chout; |x % 10 + '0');
corp;
proc coords(int left, right; bool extraSpace)void:
int c;
write(Chout; if extraSpace then " " else " " fi);
for c from left upto right do
write(Chout; ' ');
digit1(c);
if extraSpace then
write(Chout; ' ');
fi;
od;
writeln(Chout;);
write(Chout; if extraSpace then " " else " " fi);
for c from left upto right do
write(Chout; ' ');
digit2(c);
if extraSpace then
write(Chout; ' ');
fi;
od;
writeln(Chout;);
corp;
/*
* doMap - part of cmd_map - called by scanning code
*/
proc doMap(int r, c; Sector_t s)void:
SectorType_t desig;
char ch;
desig := s.s_type;
ch := SectorChar[desig];
if ThisCountryNumber ~= DEITY and s.s_owner ~= ThisCountryNumber then
if not near(r, c, ThisCountryNumber, nil) then
ch := ' ';
elif s.s_owner ~= DEITY and desig ~= s_mountain then
ch := '?';
fi;
elif ThisCountryNumber = DEITY and desig = s_water then
ch := ' ';
fi;
write(Chout; ' ', ch);
corp;
/*
* special routines called if we set the map hook.
*/
proc mapCoords(int left, right)void:
coords(left, right, false);
corp;
proc mapRowStart(int r)void:
digit1(r);
digit2(r);
corp;
proc mapRowEnd(int r)void:
write(Chout; ' ');
digit1(r);
digit2(r);
writeln(Chout;);
corp;
proc mapEmpty()void:
write(Chout; " ");
corp;
proc cmd_map()bool:
Sector_t s;
if reqSectors("Enter sectors specification for map: ") then
setMapHook();
pretend(scanSectors(doMap), void);
true
else
false
fi
corp;
proc cmd_route()bool:
[9] char
TRANS_LEFT = ('^', ' ', ' ', ' ', 'v', '/', '<','\\', ' '),
TRANS_RIGHT = ('^', '/', '>','\\', 'v', ' ', ' ', ' ', ' ');
Sector_t s;
int left, right, top, bottom, r, c;
ushort trans;
ItemType_t what;
SectorType_t desig;
if reqCmsgpob(&what, "Enter type of thing to map routes for: ") and
doSkipBlanks() and
reqBox(&top, &bottom, &left, &right,
"Enter sectors specification for route map: ") then
coords(left, right, true);
writeln(Chout;);
for r from top upto bottom do
digit1(r);
digit2(r);
write(Chout; ' ');
for c from left upto right do
readSector(r, c, s);
desig := s.s_type;
if ThisCountryNumber ~= DEITY and
s.s_owner ~= ThisCountryNumber then
write(Chout; " ");
else
trans := s.s_direction[what];
write(Chout; TRANS_LEFT[trans], SectorChar[desig],
TRANS_RIGHT[trans]);
fi;
od;
write(Chout; ' ');
digit1(r);
digit2(r);
writeln(Chout;);
od;
writeln(Chout;);
coords(left, right, true);
true
else
false
fi
corp;
/*
* doRadar -
* given a position and a range (x 1000), do a radar scan from there.
*/
proc doRadar(int rRow, rCol; uint rang; bool hasSonar)void:
uint MAX_RANGE = 20;
[MAX_RANGE * 2 + 1, MAX_RANGE * 2 + 1] char map;
[MAX_RANGE * 2 + 1, MAX_RANGE * 2 + 1] uint biggestShip;
Sector_t s;
Ship_t sh;
uint range1, rangeSq, distance, shipNumber, size;
int top, bottom, left, right, r, c;
SectorType_t desig;
char ch;
range1 := min(MAX_RANGE, rang / 1000 + 1);
top := rRow - range1;
bottom := rRow + range1;
left := rCol - range1;
right := rCol + range1;
rangeSq := make(rang, ulong) * rang / (1000 * 1000);
/* first, fill in the map with terrain values */
for r from top upto bottom do
for c from left upto right do
distance := findDistance(r, c, rRow, rCol);
if distance <= rangeSq then
readSector(r, c, s);
desig := s.s_type;
if desig ~= s_mountain and s.s_owner ~= DEITY and
s.s_owner ~= ThisCountryNumber and
distance > rangeSq / 4 then
ch := '?';
else
ch := SectorChar[desig];
fi;
else
ch := ' ';
fi;
map[range1 + r - rRow, range1 + c - rCol] := ch;
biggestShip[range1 + r - rRow, range1 + c - rCol] := 0;
od;
od;
/* next, fill in all ships that are in range */
if World.w_shipNext ~= 0 then
for shipNumber from 0 upto World.w_shipNext - 1 do
readShip(shipNumber, sh);
if sh.sh_owner ~= DEITY then /* wrecks don't show up */
r := unTransRow(ThisCountryNumber, sh.sh_row);
if r >= rRow + World.w_rows / 2 then
r := r - World.w_rows;
elif r <= rRow - World.w_rows / 2 then
r := r + World.w_rows;
fi;
c := unTransCol(ThisCountryNumber, sh.sh_col);
if c >= rCol + World.w_columns / 2 then
c := c - World.w_columns;
elif c <= rCol - World.w_columns / 2 then
c := c + World.w_columns;
fi;
distance := findDistance(r, c, rRow, rCol);
size := World.w_shipSize[sh.sh_type];
if sh.sh_type = st_submarine then
size := if hasSonar then 15 else 0 fi;
fi;
if distance <= make(rangeSq, ulong) * size * size / 1018 then
if sh.sh_type ~= st_submarine then
write(Chout; &Country[sh.sh_owner].c_name[0], ' ');
fi;
writeln(Chout; getShipName(sh.sh_type), " \#", shipNumber,
" at ", r, ',', c);
r := range1 + r - rRow;
c := range1 + c - rCol;
if size > biggestShip[r, c] then
biggestShip[r, c] := size;
if map[r, c] = SectorChar[s_water] then
map[r, c] := ShipChar[sh.sh_type] - 32;
fi;
fi;
fi;
fi;
od;
fi;
/* now display the resulting map */
coords(left, right, false);
writeln(Chout;);
for r from top upto bottom do
digit1(r);
digit2(r);
for c from left upto right do
write(Chout; ' ', map[range1 + r - rRow, range1 + c - rCol]);
od;
write(Chout; ' ');
digit1(r);
digit2(r);
writeln(Chout;);
od;
writeln(Chout;);
coords(left, right, false);
corp;
proc cmd_radar()bool:
Sector_t s;
Ship_t sh;
int row, col;
uint shipNumber;
bool isShip;
if reqSectorOrShip(&row, &col, &shipNumber, &isShip,
"Enter sector or ship to scan from: ") then
if isShip then
readShip(shipNumber, sh);
if sh.sh_owner ~= ThisCountryNumber then
err("that ship doesn't belong to you");
else
if updateShip(shipNumber, sh) then
writeShip(shipNumber, sh);
fi;
doRadar(unTransRow(ThisCountryNumber, sh.sh_row),
unTransCol(ThisCountryNumber, sh.sh_col),
World.w_shipRange[sh.sh_type] * sh.sh_efficiency,
sh.sh_type = st_destroyer or sh.sh_type =st_submarine);
fi;
else
accessSector(row, col, s);
if s.s_owner ~= ThisCountryNumber then
err("that sector doesn't belong to you");
elif s.s_type ~= s_radar then
err("that sector isn't a radar station");
else
doRadar(row, col, s.s_efficiency * World.w_radarFactor,
false);
fi;
fi;
true
else
false
fi
corp;
proc cmd_weather()void:
int top, bottom, left, right, r, c, w;
if reqBox(&top, &bottom, &left, &right, "Enter region to map: ") then
coords(left, right, false);
writeln(Chout;);
for r from top upto bottom do
digit1(r);
digit2(r);
for c from left upto right do
w := weather(transRow(r), transCol(c));
if w < -9 then
write(Chout; '-', -w - 10 + 'A');
elif w > 9 then
write(Chout; '+', w - 10 + 'A');
elif w > 0 then
write(Chout; '+', w);
else
write(Chout; w : 2);
fi;
od;
write(Chout; ' ');
digit1(r);
digit2(r);
writeln(Chout;);
od;
writeln(Chout;);
coords(left, right, false);
writeln(Chout; "Extreme low pressure center at ",
unTransRow(ThisCountryNumber, World.w_loRow / 4), ',',
unTransCol(ThisCountryNumber, World.w_loCol / 4),
", extreme high at ",
unTransRow(ThisCountryNumber, World.w_hiRow / 4), ',',
unTransCol(ThisCountryNumber, World.w_hiCol / 4), '.');
fi;
corp;
proc cmd_forecast()bool:
Sector_t s;
uint time, rang, range1, rangeSq, distance;
int top, bottom, left, right, wRow, wCol, r, c, wea;
if reqSector(&wRow, &wCol, "Sector of weather station? ") and
doSkipBlanks() and
reqPosRange(&time, 127,
"How many half-hours in the future? ") then
accessSector(wRow, wCol, s);
if s.s_owner ~= ThisCountryNumber then
err("you don't own that sector");
elif s.s_type ~= s_weather then
err("sector isn't a weather station");
elif s.s_efficiency < 60 then
err("station isn't efficient enough for forecasting");
elif time > readQuan(s, it_civilians) then
err("not enough workers for that accurate a forecast");
else
weatherPreserve();
while time ~= 0 do
time := time - 1;
weatherStep();
od;
rang := make(s.s_efficiency, uint) * 70;
range1 := rang / 1000 + 1;
top := wRow - range1;
bottom := wRow + range1;
left := wCol - range1;
right := wCol + range1;
rangeSq := make(rang, ulong) * rang / (1000 * 1000);
coords(left, right, false);
writeln(Chout;);
for r from top upto bottom do
digit1(r);
digit2(r);
for c from left upto right do
if findDistance(r, c, wRow, wCol) <= rangeSq then
wea := weather(transRow(r), transCol(c));
if wea < -9 then
write(Chout; '-', -wea - 10 + 'A');
elif wea > 9 then
write(Chout; '+', wea - 10 + 'A');
elif wea > 0 then
write(Chout; '+', wea);
else
write(Chout; wea : 2);
fi;
else
write(Chout; " ");
fi;
od;
write(Chout; ' ');
digit1(r);
digit2(r);
writeln(Chout;);
od;
writeln(Chout;);
coords(left, right, false);
writeln(Chout; "Extreme low pressure center at ",
unTransRow(ThisCountryNumber, World.w_loRow / 4), ',',
unTransCol(ThisCountryNumber, World.w_loCol / 4),
", extreme high at ",
unTransRow(ThisCountryNumber, World.w_hiRow / 4), ',',
unTransCol(ThisCountryNumber, World.w_hiCol / 4), '.');
weatherRestore();
fi;
true
else
false
fi
corp;